#pragma once
#include "token.h"
#include "vm.h"
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

/**
 * @brief 词法解析器
 *
 */
class Parser {
public:
  /**
   * @brief Construct a new Parser object by copy
   *
   * @param file_path 文件路径（包含文件名）
   * @param source_code 源代码
   * @param parent 父解析器
   * @param vm 所属虚拟机
   */
  Parser(const std::string &file_path, const std::string &source_code,
         Parser *parent, VM *vm);

  /**
   * @brief Construct a new Parser object by move
   *
   * @param file_path 文件路径（包含文件名）
   * @param source_code 源代码
   * @param parent 父解析器
   * @param vm 所属虚拟机
   */
  Parser(std::string &&file_path, std::string &&source_code, Parser *parent,
         VM *vm);

  /**
   * @brief 迭代器向前推进，获取下一个字符
   *
   */
  auto getNextChar() noexcept -> void;

  /**
   * @brief 获取下一个单词
   *
   */
  auto getNextToken() noexcept -> void;

#ifdef NDEBUG
private:
#endif
/**
 * @brief 判断字符串是关键字，还是用户自定义变量名
 * 
 */
  auto idOrToken(std::string_view id) noexcept -> Token::TokenType;

  /**
   * @brief 跳过空白字符
   * 
   */
  auto skipBlanks() noexcept -> void;

  /**
   * @brief 解析标识符
   * 
   * @param type 
   */
  auto parseId(Token::TokenType type) noexcept -> void;

  auto parseUnicodeCodePoint(std::vector<uint8_t>& buf) -> void;

#ifdef NDEBUG
private:
#endif
  std::string filePath{""};
  std::string sourceCode{""};
  std::string::const_iterator nextCharPtr{};
  char curChar{0};

  Token curToken{};
  Token preToken{};
  size_t interpolationExpectRightParenNum{0};
  Parser *parent;
  VM *vm;
};